再繼續往RxJS的道路之前,
先插播一則文章,回過頭來看Angular元件、服務、生命週期與執行的順序
透過ng cli產出的元件,底下都會有以下兩個方法(Method)
constructor() Typescript的構建物件函式ngOnInit() Angular元件初始化時執行在初學階段,這兩者都可以視作元件初始化時做的事情
只要知道ngOnInit執行的時機點晚於constructor一些
因為constructor() Typescript層的東西
其中小括號內()是構建函式的Input參數(Parameter)
把這個物件所需要用到、所依賴的服務注入進來,提供給這整個物件使用(讓物件內的每個方法都可以取用到)
昨天看到的 HttpClient 是Angular內建的眾多服務(Service)之一,就是透過注入服務到元件中讓元件能使用該服務底下的方法。未來我們也會自行寫服務service.ts,注入到自己寫的元件中。
所以執行順序為,
先執行構建物件,等構建完畢之後才執行Angular元件初始化
  constructor() {
    console.log('==== constructor ====')
  }
  ngOnInit(): void {
    console.log('==== ngOnInit ====')
  }

除了以上兩種預設的方法之外,還有很多內建方法
export class AppComponent implements OnInit, OnDestroy, AfterViewInit {
  constructor() {
    console.log('==== constructor ====')
  }
  ngOnInit(): void {
    console.log('==== ngOnInit ====')
  }
  ngAfterViewInit(): void {
    console.log('==== ngAfterViewInit ====')
  }
  ngOnDestroy() {
    console.log('==== ngOnDestroy ====')
  }
}
這一行
implements OnInit, OnDestroy, AfterViewInit實作介面
有加、沒加都不會對畫面產生影響因為
Javascript沒有interface,最終編譯都是相同結果
只是加了對程式碼風格較好,有助於IDE推斷介面型別
執行結果

constructor 構建一個物件首先執行的函式,在這裡引入物件所需用到的服務ngOnInit 生命週期 元件初始化,進入此元件做的事情,此時畫面尚未生成完畢ngAfterViewInit 生命週期 當畫面(View)渲染完畢才做的事
例如抓取頁面上的某個節點,若在畫面出現之前執行的話會抓不到元素而變成
undefined
ngOnDestroy 生命週期 離開、結束此元件時做的事情
刷新頁面或離開頁面都不會觸發效果
因為是這兩件事情主導權不在Angular手上,而是由瀏覽器銷毀
在未來提及Rouing切換頁面元件時可以看到效果
以人類的生命週期來對應的話,分別是
constructor 建構胚胎卵,注入所需要的養分服務,以幫助未來成長ngOnInit 元件在媽媽的肚子裡面長好了ngAfterViewInit 畫面生出來了,我們肉眼看的見四肢了destroy 生命離開肉體軀殼,被大自然回收了我們在 app 與 store 兩個元件中,都分別印出以上四種狀態
修改 store.component.ts
...
export class StoreComponent implements OnInit, AfterViewInit, OnDestroy {
  constructor() {
    console.log('==== StoreComponent constructor ====')
  }
  ngOnInit(): void {
    console.log('==== StoreComponent ngOnInit ====')
  }
  ngAfterViewInit(): void {
    console.log('==== StoreComponent ngAfterViewInit ====')
  }
  ngOnDestroy(): void {
    console.log('==== StoreComponent ngOnDestroy ====')
  }
}
修改 app.component.ts
export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
  title = 'project03';
  constructor() {
    console.log('==== AppComponent constructor ====')
  }
  ngOnInit(): void {
    console.log('==== AppComponent ngOnInit ====')
  }
  ngAfterViewInit(): void {
    console.log('==== AppComponent ngAfterViewInit ====')
  }
  ngOnDestroy(): void {
    console.log('==== AppComponent ngOnDestroy ====')
  }
}
修改 app.component.html
<app-store></app-store>
結果畫面

可以看到巢狀的執行順序
先是App的建構,建構完畢跑進Store開始建構,接著開始Angular的生命週期,
從APP開始初始化,等Store初始化好了、畫面都好了,最終APP的畫面才好。
透過ng cli建立一個名為svc的服務
> ng g s svc
修改svc.service.ts
import { Injectable, OnInit } from '@angular/core';
@Injectable({
  providedIn: 'root'
})
export class SvcService implements OnInit{
  constructor() {
    console.log('SvcService constructor')
  }
  
}
接著分別在app.component.ts 與store.component.ts 中
加上這一段試試看效果
  constructor(svc: SvcService) {
  }
僅將svc: SvcService加在 app.component.ts 的結果
僅將svc: SvcService加在 store.component.ts 的結果
由此可見,注入的服務是在Construct()的前一刻先被執行
服務(Service)沒有Angular生命週期
就算加了ngOnInit等方法,也不會有任何作用
Angular生命週期只有元件(Component)、指示(Directive)有
import { Injectable, OnInit } from '@angular/core';
@Injectable({
  providedIn: 'root'
})
export class SvcService implements OnInit{
  constructor() {
    console.log('SvcService constructor')
  }
  ngOnInit() {
    console.log('SvcService ngOnInit')
  }
}